import React, { createContext, useContext, useRef, useState } from 'react';
import { 
  TaskStatus, 
  TaskQueueItem, 
  ExecutionRecord,
  OutputFile,
  LogEntry,
  CustomTask
} from './types';
import { taskService } from '../services/ExecutionService';
import { useTaskHistoryContext } from './TaskHistoryContext';

interface TaskExecutionContextType {
  // 状态
  taskQueue: TaskQueueItem[];
  taskResults: ExecutionRecord[];
  outputFiles: OutputFile[];
  executionLogs: LogEntry[];
  isExecuting: boolean;

  // 队列操作
  addToQueue: (task: TaskQueueItem) => void;
  removeFromQueue: (taskId: string) => void;
  clearQueue: () => void;

  // 状态更新
  updateTaskStatus: (taskId: string, status: TaskStatus) => void;
  
  // 结果操作
  addTaskResult: (result: ExecutionRecord) => void;
  clearResults: () => void;
  
  // 文件操作
  addOutputFile: (file: OutputFile) => void;
  clearOutputFile: () => void;
  
  // 日志操作
  addLog: (message: string) => void;
  createTaskLogger: () => (message: string) => void;
  clearLogs: () => void;

  // 任务执行
  executeTask: (task: CustomTask) => Promise<void>;
  stopExecution: () => void;
}

const TaskExecutionContext = createContext<TaskExecutionContextType | undefined>(undefined);

export const TaskExecutionProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  // 状态管理
  const [taskQueue, setTaskQueue] = useState<TaskQueueItem[]>([]);
  const [taskResults, setTaskResults] = useState<ExecutionRecord[]>([]);
  const [outputFiles, setOutputFiles] = useState<OutputFile[]>([]);
  const [executionLogs, setExecutionLogs] = useState<LogEntry[]>([]);
  const [isExecuting, setIsExecuting] = useState(false);

  // 引用
  const outputFilesRef = useRef<OutputFile[]>([]);
  const executionLogsRef = useRef<LogEntry[]>([]);
  const eventSourceRef = useRef<{ close: () => void } | null>(null);

  // 获取历史记录上下文
  const { addExecutionRecord } = useTaskHistoryContext();

  // 队列操作
  const addToQueue = (task: TaskQueueItem) => {
    setTaskQueue(prev => [...prev, task]);
  };

  const removeFromQueue = (taskId: string) => {
    setTaskQueue(prev => prev.filter(task => task.id !== taskId));
  };

  const clearQueue = () => {
    setTaskQueue([]);
  };

  // 状态更新
  const updateTaskStatus = (taskId: string, status: TaskStatus) => {
    setTaskQueue(prev =>
      prev.map(task =>
        task.id === taskId ? { ...task, status } : task
      )
    );
  };

  // 结果操作
  const addTaskResult = (result: ExecutionRecord) => {
    setTaskResults(prev => [...prev, result]);
  };

  const clearResults = () => {
    setTaskResults([]);
  };

  // 文件操作
  const addOutputFile = (file: OutputFile) => {
    setOutputFiles(prev => [...prev, file]);
    outputFilesRef.current = [...outputFilesRef.current, file];
  };

  const clearOutputFile = () => {
    setOutputFiles([]);
    outputFilesRef.current = [];
  };

  // 日志操作
  const addLog = (message: string) => {
    const log: LogEntry = {
      createdAt: new Date().toISOString(),
      message
    };
    setExecutionLogs(prev => [...prev, log]);
    executionLogsRef.current = [...executionLogsRef.current, log];
  };

  const createTaskLogger = () => (message: string) => addLog(message);

  const clearLogs = () => {
    setExecutionLogs([]);
    executionLogsRef.current = [];
  };

  // 停止执行
  const stopExecution = () => {
    if (eventSourceRef.current) {
      eventSourceRef.current.close();
      eventSourceRef.current = null;
    }
    setIsExecuting(false);
  };

  // 任务执行
  const executeTask = async (task: CustomTask): Promise<void> => {
    if (!task) {
      addLog(`执行任务错误: 传入了一个错误的任务`);
      throw new Error('无效的任务');
    }

    // 设置执行状态
    setIsExecuting(true);
    
    // 记录任务开始时间
    const startTime = new Date();
    updateTaskStatus(task.id, 'running');
    addLog(`开始执行任务: ${task.taskTitle}`);
    
    return new Promise<void>((resolve, reject) => {
      // 封装文件检查函数
      const checkTaskFiles = async (taskId: string) => {
        try {
          const files = await taskService.getTaskFiles(taskId);
          const collectedFiles: OutputFile[] = [];
          
          if (files && files.length > 0) {
            files.forEach(file => {
              const outputFile = {
                id: taskId + ":" + file.name,
                name: file.name,
                type: file.type,
                size: file.size,
              };
              addOutputFile(outputFile);
              collectedFiles.push(outputFile);
            });
          }
          
          return collectedFiles;
        } catch (error) {
          console.error('获取任务文件失败:', error);
          return [];
        }
      };

      // 清理函数
      let cleanup = () => {
        if (eventSourceRef.current) {
          eventSourceRef.current.close();
          eventSourceRef.current = null;
        }
        setIsExecuting(false);
      };

      // 任务执行逻辑
      taskService.createTask(task.taskGuide)
        .then(response => {
          const addTaskLog = createTaskLogger();
          
          // 监听任务事件
          eventSourceRef.current = taskService.getTaskEvents(response.task_id, (event) => {
            switch (event.type) {
              case 'status':
                updateTaskStatus(task.id, event.status as TaskStatus || 'running');
                break;
              case 'think':
              case 'tool':
              case 'act':
              case 'log':
                addTaskLog(event.result || "");
                break;
              case 'error':
                addTaskLog(`错误: ${event.message}`);
                updateTaskStatus(task.id, 'error');
                cleanup();
                reject(new Error(event.message || '任务执行出错'));
                break;
              case 'complete':
                // 计算任务持续时间
                const endTime = new Date();
                const durationStr = `${((endTime.getTime() - startTime.getTime()) / 1000).toFixed(1)}s`;
                
                // 执行一次文件检查
                checkTaskFiles(response.task_id).then((collectedFiles) => {
                  const executionRecord: ExecutionRecord = {
                    id: "uuid",  // 由后端接口使用uuid 生成
                    createdAt: new Date(),
                    taskId: task.id,
                    taskTitle: task.taskTitle,
                    taskGuide: task.taskGuide,
                    status: 'success',
                    category: task.category,
                    duration: durationStr,
                    logs: executionLogsRef.current.map(log => ({
                      createdAt: log.createdAt,
                      message: log.message
                    })),
                    outputFiles: collectedFiles
                  };
                  
                  addExecutionRecord(executionRecord);
                  addTaskResult(executionRecord);
                  removeFromQueue(task.id);
                  addTaskLog(`任务 ${task.taskTitle} 执行完成`);
                  
                  cleanup();
                  resolve();
                });
                break;
            }
          });
        })
        .catch(error => {
          const errorMessage = error instanceof Error ? error.message : '未知错误';
          addLog(`任务执行失败: ${errorMessage}`);
          updateTaskStatus(task.id, 'error');
          cleanup();
          reject(error);
        });
      
      // 设置超时保护
      const timeoutId = setTimeout(() => {
        addLog(`任务执行超时`);
        updateTaskStatus(task.id, 'error');
        cleanup();
        reject(new Error('任务执行超时'));
      }, 30 * 60 * 1000); // 30分钟超时
      
      // 清理超时计时器
      const originalCleanup = cleanup;
      cleanup = () => {
        clearTimeout(timeoutId);
        originalCleanup();
      };
    });
  };

  const value = {
    taskQueue,
    taskResults,
    outputFiles,
    executionLogs,
    isExecuting,
    addToQueue,
    removeFromQueue,
    clearQueue,
    updateTaskStatus,
    addTaskResult,
    clearResults,
    addOutputFile,
    clearOutputFile,
    addLog,
    createTaskLogger,
    clearLogs,
    executeTask,
    stopExecution
  };

  return (
    <TaskExecutionContext.Provider value={value}>
      {children}
    </TaskExecutionContext.Provider>
  );
};

export const useTaskExecutionContext = () => {
  const context = useContext(TaskExecutionContext);
  if (context === undefined) {
    throw new Error('useTaskExecutionContext must be used within a TaskExecutionProvider');
  }
  return context;
}; 